﻿using System;
namespace NumericalSolution {
  abstract class Convection1D {
    
    protected double p_deltaX;
    protected double p_deltaTime;
    protected double p_currentTime;
    protected double[] p_next_u;
    protected double[] p_current_u;
    protected int p_numberOfNodes = 150;
    protected WaveType p_waveType;

    public enum WaveType {
      Gaussian,
      Square
    }

    public double DeltaX {
      get { return p_deltaX; }
      set { p_deltaX = value; }
    }

    public double DeltaTime {
      get { return p_deltaTime; }
      set { p_deltaTime = value; }
    }

    public double CurrentTime {
      get { return p_currentTime; }
    }

    public int NumberOfNodes {
      get { return p_numberOfNodes; }
      set { p_numberOfNodes = value; }
    }

    public WaveType Type {
      get { return p_waveType; }
      set { p_waveType = value; }
    }

    public virtual void Prepare() {
      p_next_u = new double[p_numberOfNodes];
      p_current_u = new double[p_numberOfNodes];

      p_currentTime = 0.0;

      for (int i = 0; i < p_numberOfNodes; i++) {
        p_next_u[i] = u(i * p_deltaX);
      }
    }

    protected void Age() {
      for (int i = 0; i < p_numberOfNodes; i++) {
        p_current_u[i] = p_next_u[i];
      }
    }

    abstract public double[] Next();

    protected double a(double x, double t) {
      return (1 + Math.Pow(x, 2.0)) / 
        (1 + 2 * x * t + 2 * Math.Pow(x, 2.0) + Math.Pow(x, 4.0));
    }

    public double u(double x) {
      if (p_waveType.Equals(WaveType.Gaussian)) {
        return Gaussian(x);
      } else if (p_waveType.Equals(WaveType.Square)) {
        return Square(x);
      } else {
        return Double.NaN;
      }
    }

    private double Gaussian(double x) {
      return Math.Exp(-10 * Math.Pow(4 * x - 1, 2.0));
    }

    private double Square(double x) {
      if (x >= 0.2 && x <= 0.4) {
        return 1.0;
      } else {
        return 0.0;
      }
    }

  }
}
